package com.idea.easy.log.aspect;

import com.idea.easy.log.event.ApiLogEvent;
import com.idea.easy.log.annotation.ApiLog;
import com.idea.easy.log.model.ApiLogModel;
import com.idea.easy.log.publisher.ApiLogPublisher;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @className: ApiLogAspect
 * @description: api日志注解切面类
 * @author: salad
 * @date: 2022/6/1
 **/
@Aspect
public class ApiLogAspect {

    @Around("@annotation(com.idea.easy.log.annotation.ApiLog)")
    public Object apiLog(ProceedingJoinPoint point) throws Throwable {
        Signature signature = point.getSignature();
        //获取类名
        String className = point.getTarget().getClass().getName();
        //获取方法名
        String methodName = signature.getName();
        //获取目标方法的ApiLog注解
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        ApiLog apiLog =  method.getAnnotation(ApiLog.class);
        //获取注解的value值
        String title = apiLog.value();
        long start = System.currentTimeMillis();
        //执行目标方法
        Object result = point.proceed();
        //计算接口执行的耗时（毫秒）
        Long time = System.currentTimeMillis() - start;
        //使用model承载数据
        ApiLogModel apiLogModel = new ApiLogModel();
        apiLogModel
                .setTitle(title)
                .setTime(time)
                .setMethodClass(className)
                .setMethodName(methodName);
        //发布ApiLogEvent事件
        ApiLogPublisher.event(new ApiLogEvent(apiLogModel)).publish();
        return result;
    }

}
